package com.example.jk.core;

import java.util.ArrayList;
import java.util.List;

public class Koa {
	public List<Middleware> middlewares = new ArrayList<>();

	public void registerMiddleware(Middleware middleware) {

		if (middleware instanceof KoaPlugin) {
			((KoaPlugin) middleware).init();
		}

		middlewares.add(middleware);
	}

	public void handleRequest(Context context) {

		Log.info("中间件总数:{}", middlewares.size());
		int i = 1;

		for (Middleware middleware : middlewares) {

			Log.info("正在执行中间件:{},{}", i, middleware.getClass());

//			next= new Next() {
//				
//				@Override
//				public void handle(Context ctx) {
//					next.handle(ctx);
//				}
//			}
//			middleware.handle(context,next);

			i++;

		}

		Log.info("中间件执行完毕:{}", middlewares.size());
	}

	public void executeMiddlewares(Context ctx) {

//		Middleware composedHandler = buildComposedHandler();

//		composedHandler.handleRequest(ctx);

		Next composedMiddleware = buildComposedHandler(ctx);
		composedMiddleware.handle(ctx);

//		  Next composedHandler = buildComposedHandler();
//
//          composedHandler.handle(ctx);

	}

	private Next buildComposedHandler(Context ctx) {
		Next finalHandler = (ctx2) -> {
		};
		for (int i = middlewares.size() - 1; i >= 0; i--) {

			finalHandler = wrapMiddleware(ctx,i, middlewares.get(i), finalHandler);
		}
		return finalHandler;
	}

	private Next wrapMiddleware(Context ctx,int i, Middleware middleware, Next next) {
		
		Log.info("执行了buildComposedHandler:{},middleware{}", i, middleware);
		middleware.handle(ctx, next);
		return next;
		
//		return exchange -> {
//			Log.info("执行了buildComposedHandler:{},middleware{}", i, middleware);
//			middleware.handle(ctx, next);
////			next.handle(ctx);
//		};
	}

//	private Middleware buildComposedHandler() {
//		Next finalHandler = (c1) -> {
//		};
//		for (int i = middlewares.size() - 1; i >= 0; i--) {
//			Log.info("执行了buildComposedHandler:{},finalHandler{}", i, finalHandler);
//			finalHandler = wrapMiddleware(middlewares.get(i), finalHandler);
//		}
//		return finalHandler;
//	}
//
//	private Middleware wrapMiddleware(Middleware middleware, Middleware next) {
//		
//		
//		
//		return ( ctx,next2) -> {
//			middleware.handle(ctx, (ctx3) -> {
//			});
//			next.handle(ctx, (ctx2) -> {
//			});
//		};
//	}

	public Middleware composeMiddlewares() {
		Middleware[] middlewareArray = middlewares.toArray(new Middleware[0]);
		return (ctx, next) -> {
			Middleware current = middlewareArray[middlewareArray.length - 1];
			for (int i = middlewareArray.length - 2; i >= 0; i--) {
				current = handleMiddleware(ctx, middlewareArray[i], current);
			}
//			return current.handle(ctx, next);
//			 current.handle(ctx, next);
		};
	}

	public Middleware handleMiddleware(Context ctx, Middleware middleware, Middleware next) {
//		return () -> middleware.handle(ctx, new Next() {
//			@Override
//			public void execute(Context ctx) {
//				next.handle(ctx, this);
//			}
//		});

		middleware.handle(ctx, new Next() {
			@Override
			public void handle(Context ctx) {
				next.handle(ctx, this);
			}
		});

		return next;

	}

}